﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="VehiclesViewModel.cs" company="Concept Architecture">
//   (c) 2010 Muhammad Umer Farooq
// </copyright>
// <summary>
//   Defines the VehicleViewModel type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Hisaab.Windows.Client.ViewModel
{
    using System;
    using System.Collections.ObjectModel;
    using System.Diagnostics.Contracts;
    using System.Linq;
    using System.Windows.Forms;
    using Business.Interfaces;
    using Common;
    using Hisaab.Common;

    using Microsoft.Practices.ServiceLocation;

    using Model;

    /// <summary>
    /// Defines the <seealso cref="VehiclesViewModel"/> type.
    /// </summary>
    public class VehiclesViewModel : ViewModelBase
    {
        /// <summary>
        /// The Save Command
        /// </summary>
        public static readonly ActiveAwareCommand EditCommand = new ActiveAwareCommand();

        /// <summary>
        /// The Delete Command
        /// </summary>
        public static readonly ActiveAwareCommand DeleteCommand = new ActiveAwareCommand();

        /// <summary>
        /// The refresh command
        /// </summary>
        public static readonly ActiveAwareCommand RefreshCommand = new ActiveAwareCommand();

        /// <summary>
        /// Vehicle object
        /// </summary>
        private readonly IVehicleManager _vehicleManager;

        /// <summary>
        /// The session manager
        /// </summary>
        private readonly ISession _session;

        /// <summary>
        /// Selected Vehicle
        /// </summary>
        private Vehicle _selectedVehicle;

        /// <summary>
        /// Vehicle List
        /// </summary>
        private ObservableCollection<Vehicle> _vehicle;

        /// <summary>
        /// Initializes a new instance of the <see cref="VehiclesViewModel"/> class.
        /// </summary>
        public VehiclesViewModel()
            : this(ServiceLocator.Current.GetInstance<IVehicleManager>(), ServiceLocator.Current.GetInstance<ISession>())
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="VehiclesViewModel"/> class.
        /// </summary>
        /// <param name="vehicleManager">The Vehicle.</param>
        /// <param name="session">The session Manager</param>
        public VehiclesViewModel(IVehicleManager vehicleManager, ISession session)
        {
            Contract.Requires<ArgumentNullException>(vehicleManager != null);
            Contract.Requires<ArgumentNullException>(session != null);

            _vehicleManager = vehicleManager;
            _session = session;
        }

        /// <summary>
        /// Gets the Vehicles.
        /// </summary>
        public ObservableCollection<Vehicle> Vehicles
        {
            get
            {
                if (_vehicle == null)
                {
                    _vehicle = new ObservableCollection<Vehicle>(
                        _vehicleManager
                            .List(new Business.Entities.Vehicle { UserId = _session.LoggedUser })
                            .Select(x => x.Map<Business.Entities.Vehicle, Vehicle>()));
                }

                return _vehicle;
            }

            private set
            {
                if (value != _vehicle)
                {
                    _vehicle = value;

                    OnPropertyChanged("Vehicles");
                }
            }
        }

        /// <summary>
        /// Gets or sets the selected Vehicle.
        /// </summary>
        /// <value>
        /// The selected Vehicle.
        /// </value>
        public Vehicle SelectedVehicle
        {
            get
            {
                return _selectedVehicle;
            }

            set
            {
                if (value != _selectedVehicle)
                {
                    _selectedVehicle = value;
                    OnPropertyChanged("SelectedVehicle");
                }
            }
        }

        /// <summary>
        /// Refreshes the list.
        /// </summary>
        /// <param name="obj">The object</param>
        public void RefreshList(object obj)
        {
            Vehicles = new ObservableCollection<Vehicle>(
                _vehicleManager
                    .List(new Business.Entities.Vehicle { UserId = _session.LoggedUser })
                    .Select(x => x.Map<Business.Entities.Vehicle, Vehicle>()));
        }

        /// <summary>
        /// Edits the Vehicle.
        /// </summary>
        /// <param name="obj">The object</param>
        public void EditVehicle(object obj)
        {
            var editorViewModel = new VehicleEditorViewModel(SelectedVehicle);
            ServiceLocator.Current.GetInstance<IWindowDialogService>().ShowDialog("New Vehicle", editorViewModel);
        }

        /// <summary>
        /// Deletes the Vehicle.
        /// </summary>
        /// <param name="obj">The object</param>
        public void DeleteVehicle(object obj)
        {
            if (ServiceLocator.Current.GetInstance<IWindowDialogService>().ShowMessage(
                "Are you sure you want to delete the vehicle?",
                "Hissab",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Question)
                == DialogResult.Yes)
            {
                _vehicleManager.Delete(SelectedVehicle.Map<Vehicle, Business.Entities.Vehicle>());
                Vehicles.Remove(SelectedVehicle);
            }
        }

        /// <summary>
        /// Determines whether this instance [can edit tag].
        /// </summary>
        /// <param name="obj">The object</param>
        /// <returns>
        ///   <c>true</c> if this instance [can edit tag]; otherwise, <c>false</c>.
        /// </returns>
        public bool CanEditVehicle(object obj)
        {
            return SelectedVehicle != null;
        }

        /// <summary>
        /// Determines whether this instance [can delete tag] the specified obj.
        /// </summary>
        /// <param name="obj">The object</param>
        /// <returns>
        ///   <c>true</c> if this instance [can delete tag] the specified obj; otherwise, <c>false</c>.
        /// </returns>
        public bool CanDeleteVehicle(object obj)
        {
            return SelectedVehicle != null;
        }
    }
}